<template>
  <CDialog
    :title="title"
    v-model:visible="dialogVisible"
    :loading="loading"
    :confirmText="confirmTitle"
    cancelText="关闭"
    size="small"
    @confirm="handleConfirm"
    @cancel="dialogVisible = false"
  >
    <el-form ref="formRef" :model="formState" :rules="rules" label-position="top">
      <el-row :gutter="0">
        <el-col :span="24">
          <el-form-item label="类型" prop="dataType">
            <CSelect
              v-model="formState.dataType"
              placeholder="请选择"
              clearable
              @change="handleChangeDataType"
            >
              <el-option
                v-for="item in typeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
              <el-option
                label="部件更换"
                value="PART_REPLACE"
                v-if="props.stage == 'USE_STAGE'"
              ></el-option>
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="名称" prop="nodeName">
            <template
              #label
              v-if="props.stage == 'USE_STAGE' && formState.dataType == 'PART_REPLACE'"
            >
              <div class="node-name-form-item-label g-flex-between-center">
                <span>名称</span>
                <el-button
                  class="node-name-form-item-label__button"
                  type="primary"
                  text
                  @click="modelNodeSelectVisible = true"
                  >选择部件</el-button
                >
              </div>
            </template>
            <CSelect
              placeholder="请选择部件"
              v-model="formState.nodeName"
              disabled
              v-if="props.stage == 'USE_STAGE' && formState.dataType == 'PART_REPLACE'"
            >
            </CSelect>
            <CSelect
              filterable
              v-model="formState.nodeName"
              :placeholder="!formState.dataType ? '请先选择类型' : '请选择'"
              clearable
              :disabled="!formState.dataType"
              @change="handleChangeName"
              v-else-if="isShowNameSelect"
            >
              <el-option
                v-for="unit in nameOptions"
                :key="unit.value"
                :label="unit.label"
                :value="unit.value"
              />
            </CSelect>
            <el-input
              v-else
              v-model="formState.nodeName"
              :placeholder="!formState.dataType ? '请先选择类型' : '请输入'"
              clearable
              :disabled="!formState.dataType"
              maxlength="200"
            />
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="用量" prop="dosage">
            <CDosageAndUnit
              v-model:dosage="formState.dosage"
              :unitDisabled="formState.dataType == 'PART_REPLACE' && props.stage == 'USE_STAGE'"
              v-model:unit="formState.unit"
              placeholder="请输入"
              :digit="9"
              is-group
            ></CDosageAndUnit>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注">
            <el-input v-model="formState.remark" type="textarea" placeholder="请输入" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </CDialog>
  <CModelNodeTreeSelect
    v-model:visible="modelNodeSelectVisible"
    :modelNo="props.modelNo"
    @change="handleChange"
  />
</template>

<script lang="ts" setup name="FlowDialog">
import { withDefaults, defineProps, defineEmits, computed, watch, reactive, ref } from 'vue';
import { CDialog } from '@/components/CDialog';
import CDosageAndUnit from '@/businessComponents/CDosageAndUnit/index.vue';
import { CModelNodeTreeSelect } from '@/businessComponents/CModelNodeTreeSelect';
import {
  postCheckUnitBeforeEditSubmit,
  getNodeInfo,
  addStageFlow,
  editStageFlow
} from '@/apis/pcf/myModel/modelDetail';
import type { ProcessDataItem } from '@/apis/pcf/myModel/model/modelDetailModel';
import { getSystemDict } from '@/apis/common/common';
import type { SystemDictResult } from '@/apis/common/model/commonModel';
import { useMessage } from '@/hooks/useMessage';
import { FlowDialogOperationType } from './flow-dialog';
import { rules } from './rules';
import { uniqWith, isEqual } from 'lodash';
import { CSelect } from '@/components/CSelect';
import { ProcessStageCodeEnum } from '@/constants/enum';

interface FlowDialogProps {
  visible: boolean;
  processNo: string;
  modelNo: string;
  nodeNo: string;
  flowItem?: ProcessDataItem;
  stage: keyof typeof ProcessStageCodeEnum;
}
const props = withDefaults(defineProps<FlowDialogProps>(), {});
const emits = defineEmits(['update:visible', 'refresh']);
const { createMessage, createConfirm } = useMessage();
const dialogVisible = computed({
  get: () => {
    return props.visible;
  },
  set: (value: boolean) => {
    emits('update:visible', value);
  }
});
watch(
  () => dialogVisible.value,
  val => {
    if (val) {
      init();
    }
  }
);

const formRef = ref();
const loading = ref(false);
const modelNodeSelectVisible = ref(false);
/**
 * 表单内容
 */
const formState = reactive({
  nodeNo: '',
  processNo: '',
  dataType: '',
  nodeName: '',
  dosage: '',
  unit: 'pcs',
  remark: '',
  partNodeNo: ''
});

/**
 * 编辑时，回显的零件信息（使用阶段的部件更换时适用）
 */
const sourcePartNodeNo = ref('');
/**
 * 在编辑的时候，回显部件名称
 */
const isShowPartNameInEdit = ref(false);

/**
 * 操作类型
 */
const operationType = ref<FlowDialogOperationType>();

/**
 * 弹窗标题
 */
const title = computed(() => {
  return operationType.value === 'ADD' ? '新增输入/输出流' : '编辑输入/输出流';
});
const confirmTitle = computed(() => {
  return operationType.value === 'ADD' ? '新增' : '保存';
});

/**
 * 初始化
 */
function init() {
  loading.value = false;
  getTypeDict();
  if (!props.nodeNo) {
    operationType.value = 'ADD';
    formState.processNo = props.processNo;
    formState.nodeName = '';
    formState.dataType = '';
    formState.dosage = '';
    formState.unit = 'pcs';
    formState.remark = '';
    formState.partNodeNo = '';
  } else {
    operationType.value = 'EDIT';
    formState.nodeNo = props.nodeNo;
    getData(props.nodeNo);
  }
}

/**
 * 获取节点详情
 */
async function getData(nodeNo: string) {
  try {
    loading.value = true;
    const res = await getNodeInfo(nodeNo);
    formState.dataType = res.dataType;
    if (res.dataType == 'PART_REPLACE' && props.stage == 'USE_STAGE') {
      sourcePartNodeNo.value = res.quotationNo;
      formState.partNodeNo = res.quotationNo;
    } else {
      getNameOptions();
    }
    formState.nodeName = res.nodeName;
    formState.dosage = res.unit == 'pcs' ? res.quantity : res.dosage;
    formState.unit = res.unit;
    formState.remark = res.remark;
    console.log('getData', formState);
    loading.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}

interface INameCode {
  label: string;
  value: string;
  dataCode: string;
  nodeNo?: string;
}

type TypeOptionsType = ({
  isShowNameSelect: boolean;
  // eslint-disable-next-line no-undef
} & LabelValueOptions[0])[];

const typeDictRes = ref<SystemDictResult[]>([]);
const typeOptions = ref<TypeOptionsType>([]);
const nameOptions = ref<INameCode[]>([]);
/**
 * 是否显示名称选择框
 */
const isShowNameSelect = ref(true);
/**
 * 获取类型和名称 字典
 */
async function getTypeDict() {
  try {
    const res = await getSystemDict('FLOW');
    typeDictRes.value = res || [];
    typeOptions.value = uniqWith(
      res.map(item => {
        return {
          label: item.dataDesc,
          value: item.dataGroup,
          isShowNameSelect: !!item.dataValue
        };
      }),
      isEqual
    );
  } catch (error) {
    console.log('error', error);
  }
}

function handleChangeDataType(val: string) {
  formState.nodeName = '';
  if (val == 'PART_REPLACE' && props.stage == 'USE_STAGE') {
    formState.unit = 'pcs';
    formState.remark = '部件更换';
  } else {
    isShowPartNameInEdit.value = false;
    formState.partNodeNo = '';
    getNameOptions();
  }
}
/**
 * 选择完名称后触发
 */
const handleChangeName = (val: string) => {
  const index = nameOptions.value.findIndex(item => item.value == val);
  if (index > -1) {
    formState.unit = nameOptions.value[index].dataCode;
  }
};

/**
 * 部件更换 弹窗表格内选中操作
 */
const handleChange = (item: any) => {
  formState.nodeName = item.nodeName || '';
  formState.partNodeNo = item.nodeNo || '';

  modelNodeSelectVisible.value = false;
};

/**
 * 获取名称下拉选项
 */
function getNameOptions() {
  const item = typeOptions.value.find(item => item.value === formState.dataType);
  if (item && !item.isShowNameSelect) {
    isShowNameSelect.value = false;
    return;
  }
  isShowNameSelect.value = true;
  nameOptions.value = typeDictRes.value
    .filter(item => item.dataGroup === formState.dataType)
    .map(item => {
      return {
        label: item.dataValue,
        value: item.dataValue,
        dataCode: item.dataCode
      };
    });
}

/**
 * 保存按钮
 */
function handleConfirm() {
  console.log('handleConfirm');
  formRef.value?.validate((valid: boolean) => {
    if (valid) {
      submitFlowReq();
    }
  });
}

/**
 * 接口请求
 */
async function submitFlowReq() {
  try {
    loading.value = true;
    if (operationType.value === 'ADD') {
      await addStageFlow(formParams());
    } else {
      const checkRes = await postCheckUnitBeforeEditSubmit(props.nodeNo as string, formState.unit);
      if (!checkRes) {
        createConfirm('修改不一致的用量单位', '已关联的因子需要重新选择，是否继续', {
          iconType: 'warning',
          confirmButtonText: '继续提交',
          cancelButtonText: '取消修改'
        })
          .then(() => {
            handleEditNodeReq();
          })
          .catch(() => {
            loading.value = false;
          });
        return;
      }
      handleEditNodeReq();
      return;
    }
    createMessage.success(operationType.value === 'ADD' ? '新增成功！' : '编辑成功！');
    emits('refresh', props.processNo);
    dialogVisible.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}

/**
 * 编辑节点请求
 */
async function handleEditNodeReq() {
  try {
    await editStageFlow(formParams());
    createMessage.success(operationType.value === 'ADD' ? '新增成功！' : '编辑成功！');
    emits('refresh', props.processNo);
    dialogVisible.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}
const formParams = () => {
  let partNodeNo = formState.dataType == 'PART_REPLACE' ? formState.partNodeNo : '';
  // 如果选中项在懒加载的树中
  if (isShowPartNameInEdit.value) {
    partNodeNo = sourcePartNodeNo.value;
  }
  let params = {
    nodeNo: props.nodeNo,
    processNo: formState.processNo,
    dataType: formState.dataType,
    nodeName: formState.nodeName,
    dosage: formState.dosage,
    unit: formState.unit,
    remark: formState.remark,
    partNodeNo
  };
  console.log('formParams', params);
  return params;
};
</script>
<style lang="scss" scoped>
.node-name-form-item-label {
  display: inline-flex;
  .node-name-form-item-label__button {
    position: absolute;
    right: 0;
  }
}
</style>
